package com.example.netty.sockettwo;

import com.alibaba.fastjson.JSON;
import com.example.netty.common.FieldClass;
import com.example.netty.pojo.*;
import com.example.netty.service.bak1.Bak1ServiceImpl;
import com.example.netty.service.bak1warning.Bak1ServiceWarningImpl;
import com.example.netty.service.bak2.Bak2ServiceImpl;
import com.example.netty.service.bak2warning.Bak2WarningServiceImpl;
import com.example.netty.service.communication.CommunicationServiceImpl;
import com.example.netty.service.gpspostitiondevice.GpsPostitionDeviceServiceImpl;
import com.example.netty.service.hyb.HybServiceImpl;
import com.example.netty.service.hybwarning.HybWarningServiceImpl;
import com.example.netty.service.hycyw.HycywServiceImpl;
import com.example.netty.service.hycywwarning.HycywWarningServiceImpl;
import com.example.netty.service.hymain.HyMainServiceImpl;
import com.example.netty.service.hymainwarning.HyMainWarningServiceImpl;
import com.example.netty.service.leftmain.LeftMainServiceImpl;
import com.example.netty.service.leftmainwarning.LeftMainWarningServiceImpl;
import com.example.netty.service.offside.OffsideServiceImpl;
import com.example.netty.service.power1.Power1ServiceImpl;
import com.example.netty.service.power1warning.Power1WarningServiceImpl;
import com.example.netty.service.power2.Power2ServiceImpl;
import com.example.netty.service.power2warning.Power2WarningServiceImpl;
import com.example.netty.service.power3.Power3ServiceImpl;
import com.example.netty.service.power3warning.Power3WarningServiceImpl;
import com.example.netty.service.powerbak.PowerBakServiceImpl;
import com.example.netty.service.powerbakwarning.PowerBakWarningServiceImpl;
import com.example.netty.service.rightmain.RightMainServiceImpl;
import com.example.netty.service.rightmainwarning.RightMainWarningServiceImpl;
import com.example.netty.service.shiplogdevice.ShiplogDeviceServiceImpl;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


@Component
public class NettyServerHandlerTwo extends ChannelInboundHandlerAdapter implements ApplicationContextAware {
    private static ApplicationContext context;
    private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private static final Logger log = LoggerFactory.getLogger(NettyServerHandlerTwo.class);
    private static final ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);



    /**
     * 客户端连接会触发
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端已连接服务端");
        Channel incoming = ctx.channel();
        clients.add(incoming);

    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端已断开连接");
        Channel incoming = ctx.channel();
        clients.remove(incoming);

    }

    /**
     * 客户端发消息会触发
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//        Map<String, Object> map = listAllFive();
//        String responseJson = JSON.toJSONString(map);
//        log.info("数据: {}", responseJson);
//        TextWebSocketFrame responseFrame = new TextWebSocketFrame(responseJson);
//        ctx.writeAndFlush(responseFrame);

    }

    public Map<String, Object> listAllFive(String bucketName) throws Exception {
        Map<String, Object> fmap = new HashMap<>();
        LeftMainServiceImpl leftMainService = this.context.getBean(LeftMainServiceImpl.class);
        LeftMainWarningServiceImpl leftMainWarningService = this.context.getBean(LeftMainWarningServiceImpl.class);
        FieldClass.fieldCompare(LeftMain.class, leftMainService.findOne(bucketName), leftMainWarningService.findOne(bucketName), fmap);
//
        RightMainServiceImpl rightMainService = this.context.getBean(RightMainServiceImpl.class);
        RightMainWarningServiceImpl rightMainWarningService = this.context.getBean(RightMainWarningServiceImpl.class);
        FieldClass.fieldCompare(RightMain.class, rightMainService.findOne(bucketName), rightMainWarningService.findOne(bucketName), fmap);
//
        Power1ServiceImpl power1Service = this.context.getBean(Power1ServiceImpl.class);
        Power1WarningServiceImpl power1WarningService = this.context.getBean(Power1WarningServiceImpl.class);
        FieldClass.fieldCompare(Power1.class, power1Service.findOne(bucketName), power1WarningService.findOne(bucketName), fmap);

        Power2ServiceImpl power2Service = this.context.getBean(Power2ServiceImpl.class);
        Power2WarningServiceImpl power2WarningService = this.context.getBean(Power2WarningServiceImpl.class);
        FieldClass.fieldCompare(Power2.class, power2Service.findOne(bucketName), power2WarningService.findOne(bucketName), fmap);

        Power3ServiceImpl power3Service = this.context.getBean(Power3ServiceImpl.class);
        Power3WarningServiceImpl power3WarningService = this.context.getBean(Power3WarningServiceImpl.class);
        FieldClass.fieldCompare(Power3.class, power3Service.findOne(bucketName), power3WarningService.findOne(bucketName), fmap);
//
        PowerBakServiceImpl powerBakService = this.context.getBean(PowerBakServiceImpl.class);
        PowerBakWarningServiceImpl powerBakWarningService = this.context.getBean(PowerBakWarningServiceImpl.class);
        FieldClass.fieldCompare(PowerBak.class, powerBakService.findOne(bucketName), powerBakWarningService.findOne(bucketName), fmap);
//
        HyMainServiceImpl hyMainService = this.context.getBean(HyMainServiceImpl.class);
        HyMainWarningServiceImpl hyMainWarningService = this.context.getBean(HyMainWarningServiceImpl.class);
        FieldClass.fieldCompare(HyMain.class, hyMainService.findOne(bucketName), hyMainWarningService.findOne(bucketName), fmap);
//
        Bak1ServiceImpl bak1Service = this.context.getBean(Bak1ServiceImpl.class);
        Bak1ServiceWarningImpl bak1WarningService = this.context.getBean(Bak1ServiceWarningImpl.class);
        FieldClass.fieldCompare(Bak1.class, bak1Service.findOne(bucketName), bak1WarningService.findOne(bucketName), fmap);

        Bak2ServiceImpl bak2Service = this.context.getBean(Bak2ServiceImpl.class);
        Bak2WarningServiceImpl bak2WarningService = this.context.getBean(Bak2WarningServiceImpl.class);
        FieldClass.fieldCompare(Bak2.class, bak2Service.findOne(bucketName), bak2WarningService.findOne(bucketName), fmap);

        HycywServiceImpl hycywService = this.context.getBean(HycywServiceImpl.class);
        HycywWarningServiceImpl hycywWarningService = this.context.getBean(HycywWarningServiceImpl.class);
        FieldClass.fieldCompare(Hycyw.class, hycywService.findOne(bucketName), hycywWarningService.findOne(bucketName), fmap);

        HybServiceImpl hybService = this.context.getBean(HybServiceImpl.class);
        HybWarningServiceImpl hybWarningService = this.context.getBean(HybWarningServiceImpl.class);
        FieldClass.fieldCompare(Hyb.class, hybService.findOne(bucketName), hybWarningService.findOne(bucketName), fmap);


//
        OffsideServiceImpl iOffsideService = this.context.getBean(OffsideServiceImpl.class);

        GpsPostitionDeviceServiceImpl gpsPostitionDeviceService = this.context.getBean(GpsPostitionDeviceServiceImpl.class);

        ShiplogDeviceServiceImpl shiplogDeviceService=this.context.getBean(ShiplogDeviceServiceImpl.class);

        fmap.put("iOffside", iOffsideService.eightList(bucketName));
        fmap.put("newiOffside", iOffsideService.newList(bucketName));
        fmap.put("gpsPostitionDeviceService", gpsPostitionDeviceService.findOne(bucketName));
        fmap.put("shiplogDeviceService", shiplogDeviceService.findOne(bucketName));
        fmap.put("state",true);




//        CommunicationMapper communicationMapper = this.context.getBean(CommunicationMapper.class);
//        fmap.put("communication",   communicationMapper.selectById(1));


        return fmap;
    }

    public  void sendToAllClients(TextWebSocketFrame message) {
        // 遍历所有连接的客户端，将消息写入到通道中
        for (Channel channel : clients) {
            TextWebSocketFrame newMessage = new TextWebSocketFrame(message.content().copy());
            channel.writeAndFlush(newMessage);

        }
    }

    /**
     * 数据读取完毕事件
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
//        log.info("服务端读取完毕: {}");
    }

    /**
     * 发生异常触发
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("程序异常");
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
        scheduler.scheduleAtFixedRate(() -> {
            try {
                CommunicationServiceImpl communicationService = this.context.getBean(CommunicationServiceImpl.class);
                boolean exist = communicationService.isExist("ship_two");
                log.info("shipTwo信号: {}", exist);
                String responseJson = null;
                if(!exist){
                    responseJson="{\"state\":false}";
                }else {
                    long startTime = System.currentTimeMillis();
                    Map<String, Object> map = listAllFive("ship_two");
                    long endTime = System.currentTimeMillis();
                    log.info("shipOne执行的时间: {}",  endTime - startTime);
                    responseJson=JSON.toJSONString(map);
                }
//                log.info("shipTwo数据: {}", responseJson);
                TextWebSocketFrame responseFrame = new TextWebSocketFrame(responseJson);
                // 将消息发送给所有连接的客户端
                sendToAllClients(responseFrame);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, 0, 1, TimeUnit.SECONDS);

    }
}

